/*
 * Copyright 2024 The JA-SIG Collaborative. All rights reserved.
 * distributed with thi file and available online at
 */
package com.lap.permission.api;

import com.lap.framework.context.helper.UserHelper;
import com.lap.framework.dto.page.PageDTO;
import com.lap.framework.enums.YesNo;
import com.lap.framework.exception.ExceptionHandler;
import com.lap.framework.validator.Update;
import com.lap.framework.watchdog.annotation.Repeat;
import com.lap.permission.convert.Convert;
import com.lap.permission.domain.entity.User;
import com.lap.permission.domain.pojo.UserState;
import com.lap.permission.dto.query.UserQuery;
import com.lap.permission.dto.request.UserRequest;
import com.lap.permission.dto.request.UserStateRequest;
import com.lap.permission.dto.response.UserDTO;
import com.lap.permission.dto.response.UserInfoDTO;
import com.lap.permission.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <pre>
 *  系统管理员 Controller,控制业务流程。
 *  提供包括业务流程校验,业务流程控制。当流程非常复杂时候,请在API和Service之间添加一层Manager。
 *  Controller 对外开放Rest,同时可以做简单流程控制。Manager复杂流程控制。Service数据完整性(事务)。DAO/Mapper持久操作。
 *  流程简单: Controller->Service->DAO
 *  复杂流程: Controller->Manager->Service->DAO
 *  对外流程: Controller->Manager->Service->DAO
 * 					    |->外部服务
 *  <b>uri 规则</b>
 *   uri 名词复数.
 *   列表或分页 : GET /persons
 *   单人信息   : GET /persons/1
 *   新增      : POST /persons
 *   修改      : PUT /persons
 *   删除      : DELETE /persons/1
 * </pre>
 *
 * @author Shuisheng Lao(劳水生)
 * @version 0.0.1
 * @see UserService
 * @see UserRequest
 * @see User
 */
@Tag(name = "系统管理员")
@RequiredArgsConstructor
@RestController
@RequestMapping("api/users")
public class UserController {
    public static final String NUMBER = "10102";

    private final UserService userService;

    private final Convert convert;

    @Operation(summary = "管理员列表")
    @GetMapping
    public PageDTO<List<UserDTO>> queryPage(UserQuery query) {
        return userService.queryPage(query);
    }

    @Operation(summary = "管理员选择")
    @GetMapping("select")
    public PageDTO<List<User>> querySelect(UserQuery query) {
        return userService.querySelect(query);
    }

    @Operation(summary = "管理员登录")
    @GetMapping("me")
    public UserInfoDTO queryForMe() {
        return userService.queryUserInfo(UserHelper.getUserId());
    }

    @Operation(summary = "管理员渲染")
    @PostMapping("list")
    public List<User> queryByIds(@RequestBody List<Integer> list) {
        if (CollectionUtils.isEmpty(list))
            return Collections.emptyList();

        List<Integer> ids = list.stream().distinct().sorted().toList();
        return userService.queryByIds(ids);
    }

    @Operation(summary = "管理员获取")
    @GetMapping("{userId}")
    public User queryById(@PathVariable Integer userId) {
        return userService.queryById(userId);
    }

    @Operation(summary = "管理员新增")
    @Repeat
    @PostMapping
    public Integer saveUser(@RequestBody @Valid UserRequest request) {
        User query = userService.queryByUsername(request.getUsername());
        if (Objects.nonNull(query))
            ExceptionHandler.execInterrupt("10101");

        User user = convert.toUser(request);
        user.setTypeFlag(YesNo.NO.getValue());
        //TODO 密码加密
        return userService.insertUser(user);
    }

    @Operation(summary = "管理员更新")
    @Repeat
    @PutMapping
    public Integer updateUser(@RequestBody @Validated(Update.class) UserRequest request) {
        User query = userService.queryByUsername(request.getUsername());
        if (Objects.nonNull(query) && !Objects.equals(query.getId(), request.getId()))
            ExceptionHandler.execInterrupt("10101");

        return userService.updateUser(convert.toUser(request));
    }

    @Operation(summary = "管理员启用")
    @Repeat
    @PutMapping("enable")
    public Integer enableUser(@RequestBody @Valid UserStateRequest request) {
        User query = userService.queryById(request.getId());
        if (Objects.isNull(query))
            throw ExceptionHandler.newBiz(NUMBER);

        UserState userState = convert.toUserState(request);
        userState.setStatusFlag(YesNo.YES.getValue());
        return userService.updateState(userState);
    }

    @Operation(summary = "管理员禁用")
    @Repeat
    @PutMapping("disable")
    public Integer disableUser(@RequestBody @Valid UserStateRequest request) {
        User query = userService.queryById(request.getId());
        if (Objects.isNull(query))
            throw ExceptionHandler.newBiz(NUMBER);

        UserState userState = convert.toUserState(request);
        userState.setStatusFlag(YesNo.NO.getValue());
        return userService.updateState(userState);
    }

    @Operation(summary = "管理员删除")
    @Repeat
    @DeleteMapping("{userId}")
    public Integer deleteById(@PathVariable Integer userId) {
        return userService.deleteById(userId);
    }

}
